package com.binguo.wxapi.controller;

import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.LoggerUtil;

import com.binguo.model.model.Customer;
import com.binguo.model.model.PayCard;
import com.binguo.model.repository.CustomerRepository;
import com.binguo.service.OrderService;
import com.binguo.wxapi.form.external.GetCustomerInfoForm;
import com.binguo.wxapi.form.external.OrderListForm;
import com.binguo.wxapi.form.external.RechargeForm;
import com.binguo.wxapi.form.external.RegisterForm;
import com.binguo.wxapi.result.Result;
import com.binguo.wxapi.result.ResultGenerator;
import com.binguo.wxapi.service.ABCBankService;
import com.binguo.wxapi.service.RedisLockService;
import com.binguo.wxapi.util.EncryptUtils;
import com.binguo.wxapi.vo.external.CustomerVO;
import com.binguo.wxapi.vo.external.OrderResultVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.util.*;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;


@RestController
@RequestMapping
public class ExternalApiController {

    public static String key = "CC1745453991EC29BFEDD5F80A2D5BF0";


    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    ABCBankService abcBankService;
    @Autowired
    OrderService orderService;



    @Resource
    RedisLockService redisLockService;


    /**
     * 注册
     * @param registerForm
     * @return
     */
    @PostMapping(value = "/api/wxapp/public/registerOrAddFace", produces = APPLICATION_JSON_VALUE)
    public Result registerOrAddFace(@RequestBody RegisterForm registerForm) {
        if (StringUtils.isEmpty(registerForm.getPhone())
                || StringUtils.isEmpty(registerForm.getSign())
                || StringUtils.isEmpty(registerForm.getFaceUrl())
                ) {
            throw new ServiceException("参数错误");
        }

        Map<String, String> param = new LinkedHashMap<>();
        param.put("faceUrl",registerForm.getFaceUrl());
        param.put("phone",registerForm.getPhone());
        param.put("username",registerForm.getUsername());

        String sign = generateSign(param, key);

        if (!key.equals(registerForm.getSign())) {

            if (!registerForm.getSign().equals(sign)) {
                throw new ServiceException("签名失败");
            }
        }

        abcBankService.register(registerForm.getPhone(), registerForm.getFaceUrl(), registerForm.getUsername());

        return ResultGenerator.genSuccessResult();
    }

    /**
     * 注销
     * @param getCustomerInfoForm
     * @return
     */
    @PostMapping(value = "/api/wxapp/public/close", produces = APPLICATION_JSON_VALUE)
    public Result close(@RequestBody GetCustomerInfoForm getCustomerInfoForm) {
        if (StringUtils.isEmpty(getCustomerInfoForm.getPhone())
                || StringUtils.isEmpty(getCustomerInfoForm.getSign())
                ) {
            throw new ServiceException("参数错误");
        }

        Map<String, String> param = new LinkedHashMap<>();
        param.put("phone",getCustomerInfoForm.getPhone());

        String sign = generateSign(param, key);

        if (!key.equals(getCustomerInfoForm.getSign())) {
            if (!getCustomerInfoForm.getSign().equals(sign)) {
                throw new ServiceException("签名失败");
            }
        }

        abcBankService.close(getCustomerInfoForm.getPhone());

        return ResultGenerator.genSuccessResult();
    }

    /**
     * remove
     * @return
     */
    @GetMapping(value = "/api/wxapp/public/remove", produces = APPLICATION_JSON_VALUE)
    public Result remove(String sign) {
        if (!key.equals(sign)) {
            return ResultGenerator.genFailResult("error");
        }

        abcBankService.removeAll();

        return ResultGenerator.genSuccessResult();
    }

    /**
     * 查询订单列表
     * @param orderListForm
     * @return
     */
    @PostMapping(value = "/api/wxapp/public/orderList", produces = APPLICATION_JSON_VALUE)
    public Result orderList(@RequestBody OrderListForm orderListForm) {
        if ((orderListForm.getPage() == null || orderListForm.getPage() < 1)
                || StringUtils.isEmpty(orderListForm.getSign())
                || StringUtils.isEmpty(orderListForm.getPhone())
                ) {
            throw new ServiceException("参数错误");
        }

        Map<String, String> param = new LinkedHashMap<>();
        param.put("page", orderListForm.getPage().toString());
        param.put("phone", orderListForm.getPhone());

        String sign = generateSign(param, key);

        if (!key.equals(orderListForm.getSign())) {
            if(!orderListForm.getSign().equals(sign)){
                throw new ServiceException("签名失败");
            }
        }


        OrderResultVO orderResultVO = abcBankService.orderList(orderListForm.getPhone(), orderListForm.getPage());

        return ResultGenerator.genSuccessResult(orderResultVO);
    }

    /**
     *
     * @param getCustomerInfoForm
     * @return
     */
    @PostMapping(value = "/api/wxapp/public/getUserInfo", produces = APPLICATION_JSON_VALUE)
    public Result getCustomerInfo(@RequestBody GetCustomerInfoForm getCustomerInfoForm){
        if (StringUtils.isEmpty(getCustomerInfoForm.getPhone())
                || StringUtils.isEmpty(getCustomerInfoForm.getSign())
                ) {
            throw new ServiceException("参数错误");
        }

        Map<String, String> param = new LinkedHashMap<>();
        param.put("phone",getCustomerInfoForm.getPhone());

        String sign = generateSign(param, key);

        if(!getCustomerInfoForm.getSign().equals(sign)){
            throw new ServiceException("签名失败");
        }


        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone", getCustomerInfoForm.getPhone());

        List<Customer> customerList = customerRepository.findByCondition(condition);

        if (customerList != null && customerList.size() > 0) {
            Customer customer = customerList.get(0);


            CustomerVO customerVO = new CustomerVO();
            customerVO.setCustomerId(customer.getId());
            customerVO.setCustomerName(customer.getName());


            PayCard payCard = abcBankService.getPayCard(customer.getId());

            if (payCard != null) {
                customerVO.setBalance(payCard.getAccountbalance());
                customerVO.setQrCode(payCard.getPayCode());
            }else {
                customerVO.setBalance(0l);

            }

            return ResultGenerator.genSuccessResult(customerVO);
        }


        throw new ServiceException("用户不存在");
    }


    /**
     * 充值
     * @param rechargeForm
     * @return
     */
    @PostMapping(value = "/api/wxapp/public/yhcz", produces = APPLICATION_JSON_VALUE)
    public Result yhcz(@RequestBody RechargeForm rechargeForm){
        if (StringUtils.isEmpty(rechargeForm.getPhone())
                || StringUtils.isEmpty(rechargeForm.getSign())
                || StringUtils.isEmpty(rechargeForm.getAmount())
                || StringUtils.isEmpty(rechargeForm.getOrderNo())
                || StringUtils.isEmpty(rechargeForm.getOrderTime())
                ) {
            throw new ServiceException("参数错误");
        }

        try {
            LoggerUtil.console.info("recharge:{}", com.binguo.common.util.JsonUtil.toJson(rechargeForm));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        Map<String, String> param = new LinkedHashMap<>();
        param.put("amount",rechargeForm.getAmount());
        param.put("orderNo",rechargeForm.getOrderNo());
        param.put("orderTime",rechargeForm.getOrderTime());
        param.put("phone",rechargeForm.getPhone());
        param.put("username",rechargeForm.getUsername());

        String sign = generateSign(param, key);

        if(!rechargeForm.getSign().equals(sign)){
            throw new ServiceException("签名失败");
        }

        String key = rechargeForm.getOrderNo();

        String uuid = UUID.randomUUID().toString();
        boolean lock = redisLockService.setLock(key, 10000, uuid);
        if (lock) {
            abcBankService.recharge(rechargeForm);
            return ResultGenerator.genSuccessResult();
        } else {
            throw new ServiceException("订单正在处理中");
        }

    }


    private static String generateSign(Map<String, String> param, String appKey) {
        StringBuilder sb = new StringBuilder();

        for (Map.Entry<String,String> en : param.entrySet()) {
            sb.append(en.getKey()).append("=").append(en.getValue()).append("&");
        }
        sb.append("key=").append(appKey);

        String sign = EncryptUtils.md5(sb.toString()).toUpperCase();
        return sign;
    }





}
